﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace IPTV_Playlist_Editor
{
    public partial class Export : Form
    {
        private List<Channel> _channels;
        private string fileName;

        public Export(List<Channel> channels, string fileName)
        {
            InitializeComponent();
            statusStrip.Padding = new Padding(statusStrip.Padding.Left, statusStrip.Padding.Top, statusStrip.Padding.Left, statusStrip.Padding.Bottom);
            _channels = channels;
            this.fileName = fileName;
        }

        private void btnDefault_Click(object sender, EventArgs e)
        {
            tbInterface.Text = "eth0";
        }

        private void selectPath(object sender, EventArgs e)
        {
            if (folderBrowser.ShowDialog() != DialogResult.OK)
                return;

            tbPath.Text = folderBrowser.SelectedPath;
            btnExport.Enabled = true;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (exportPlaylist.IsBusy)
            {
                exportPlaylist.CancelAsync();
            }
            else
            {
                DialogResult = DialogResult.Cancel;
                Close();
                Dispose();
            }
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            if (tbInterface.Text.Trim().Length == 0)
            {
                MessageBox.Show("You must enter interface!", "Export Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            tbInterface.Enabled = false;
            tbPath.Enabled = false;
            btnDefault.Enabled = false;
            btnBrowse.Enabled = false;
            btnExport.Enabled = false;
            rbTVHeadEnd34.Enabled = false;
            rbTVHeadEnd39.Enabled = false;
            toolStripProgressBar.Maximum = _channels.Count+1;

            if (!exportPlaylist.IsBusy)
                exportPlaylist.RunWorkerAsync();
            else
                MessageBox.Show("Another exporting process is already running!", "Export Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void exportPlaylist_DoWork(object sender, DoWorkEventArgs e)
        {
            if (rbTVHeadEnd34.Checked)
                export_TVHeadEnd_34(e);
            else
                export_TVHeadEnd_39(e);
        }

        private void export_TVHeadEnd_34(DoWorkEventArgs e)
        {
            toolStripStatusLabel.Text = "Creating subfolders ...";
            Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\iptvservices");
            Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\channels");
            Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\channeltags");
            toolStripStatusLabel.Text = "Creating configuration files ...";
            List<string> tags = new List<string>();
            List<Xmltv> xmltv = new List<Xmltv>();
            for (int i = 0; i < _channels.Count; i++)
            {
                if (exportPlaylist.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }

                string[] channelTags = _channels[i].Tag.Split(',');
                List<string> tagIndexes = new List<string>();

                for (int z = 0; z < channelTags.Length; z++)
                {
                    int tagIndex = tags.IndexOf(channelTags[z]);
                    if (tagIndex == -1)
                    {
                        File.WriteAllText(@folderBrowser.SelectedPath + "\\channeltags\\" + (tags.Count + 1), "{\n\t\"enabled\": 1,\n\t\"internal\": 0,\n\t\"titledIcon\": 0,\n\t\"name\": \"" + channelTags[z] + "\",\n\t\"comment\": \"\",\n\t\"icon\": \"\",\n\t\"id\": " + (tags.Count + 1) + "\n}");
                        tags.Add(channelTags[z]);
                        tagIndexes.Add(tags.Count.ToString());
                    }
                    else if (!tagIndexes.Contains((tagIndex + 1).ToString()))
                    {
                        tagIndexes.Add((tagIndex + 1).ToString());
                    }
                }

                File.WriteAllText(@folderBrowser.SelectedPath + "\\iptvservices\\iptv_" + (i + 1), "{\n\t\"pmt\": 0,\n\t\"stype\": " + (_channels[i].Tag.Contains("Radio") || _channels[i].Tag.Contains("radio") ? 2 : 1) + ",\n\t\"port\": " + _channels[i].Port + ",\n\t\"interface\": \"" + tbInterface.Text + "\",\n\t\"group\": \"" + _channels[i].IP + "\",\n\t\"channelname\": \"" + _channels[i].Name + "\",\n\t\"mapped\": 1," + "\n\t\"pcr\": 0,\n\t\"disabled\": 0\n}");
                File.WriteAllText(@folderBrowser.SelectedPath + "\\channels\\" + (i + 1), "{\n\t\"name\": \"" + _channels[i].Name + "\",\n\t\"icon\": \"" + _channels[i].Image + "\",\n\t\"xmltv-channel\": \"" + _channels[i].EPG + "\",\n\t\"tags\": [\n\t\t" + string.Join(",", tagIndexes.ToArray()) + "\n\t],\n\t\"dvr_extra_time_pre\": 0,\n\t\"dvr_extra_time_post\": 0,\n\t\"channel_number\": " + _channels[i].ID + "\n}");

                if (_channels[i].EPG.Length > 0)
                {
                    int xmltvId = xmltv.FindIndex(epg => epg.ID == _channels[i].EPG);
                    if (xmltvId == -1)
                        xmltv.Add(new Xmltv(_channels[i].EPG, _channels[i].Name, (i + 1).ToString()));
                    else
                        xmltv[xmltvId].Channels += ", " + (i + 1).ToString();
                }

                exportPlaylist.ReportProgress(i);
            }
            if (xmltv.Count > 0)
            {
                toolStripStatusLabel.Text = "Creating subfolder for XMLTV files ...";
                Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\epggrab\\xmltv\\channels");
                toolStripStatusLabel.Text = "Creating XMLTV files ...";
                for (int c = 0; c < xmltv.Count; c++)
                {
                    File.WriteAllText(@folderBrowser.SelectedPath + "\\epggrab\\xmltv\\channels\\" + xmltv[c].ID, "{\n\t\"name\": " + xmltv[c].Name + ",\n\t\"channels\": [\n\t\t" + xmltv[c].Channels + "\n\t]\n}");
                }
            }
            exportPlaylist.ReportProgress(_channels.Count + 1);
        }

        private void export_TVHeadEnd_39(DoWorkEventArgs e)
        {
            string network_uuid = System.Guid.NewGuid().ToString("N");
            toolStripStatusLabel.Text = "Creating main subfolders ...";
            Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\epggrab\\xmltv\\channels");
            Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\channel\\tag");
            Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\channel\\config");
            Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\input\\iptv\\networks\\" + network_uuid + "\\muxes");
            toolStripStatusLabel.Text = "Creating configuration files ...";
            Dictionary<string, string> tags = new Dictionary<string, string>();
            File.WriteAllText(@folderBrowser.SelectedPath + "\\input\\iptv\\config", "{\n\t\"uuid\": \"" + System.Guid.NewGuid().ToString("N") + "\",\n\t\"skipinitscan\": true,\n\t\"autodiscovery\": false\n}");
            File.WriteAllText(@folderBrowser.SelectedPath + "\\input\\iptv\\networks\\" + network_uuid + "\\config", "{\n\t\"nid\": 0,\n\t\"networkname\": \"" + fileName + "\",\n\t\"skipinitscan\": true,\n\t\"autodiscovery\": false,\n\t\"idlescan\": false,\n\t\"max_streams\": 2,\n\t\"max_bandwidth\": 0,\n\t\"max_timeout\": 10\n}");

            for (int i = 0; i < _channels.Count; i++)
            {
                if (exportPlaylist.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }

                string[] channelTags = _channels[i].Tag.Split(',');
                List<string> tagIndexes = new List<string>();

                for (int z = 0; z < channelTags.Length; z++)
                {
                    if (!tags.ContainsKey(channelTags[z]))
                    {
                        tags.Add(channelTags[z], System.Guid.NewGuid().ToString("N"));
                        File.WriteAllText(@folderBrowser.SelectedPath + "\\channel\\tag\\" + tags[channelTags[z]], "{\n\t\"enabled\": true,\n\t\"internal\": false,\n\t\"titledIcon\": false,\n\t\"name\": \"" + channelTags[z] + "\",\n\t\"comment\": \"\",\n\t\"icon\": \"\"\n}");
                    }
                    tagIndexes.Add("\"" + tags[channelTags[z]] + "\"");
                }

                string mux_id = System.Guid.NewGuid().ToString("N"), svc_id = System.Guid.NewGuid().ToString("N"), channel_id = System.Guid.NewGuid().ToString("N"), identifier;
                char[] id = _channels[i].Name.ToCharArray();
                id = Array.FindAll<char>(id, (c => char.IsLetterOrDigit(c)));
                identifier = new string(id);
                Directory.CreateDirectory(@folderBrowser.SelectedPath + "\\input\\iptv\\networks\\" + network_uuid + "\\muxes\\" + mux_id + "\\services");
                File.WriteAllText(@folderBrowser.SelectedPath + "\\input\\iptv\\networks\\" + network_uuid + "\\muxes\\" + mux_id + "\\config", "{\n\t\"iptv_url\": \"udp://" + _channels[i].IP + ":" + _channels[i].Port + "\",\n\t\"iptv_interface\": \"" + tbInterface.Text + "\",\n\t\"iptv_atsc\": false,\n\t\"iptv_muxname\": \"" + identifier + "\",\n\t\"iptv_sname\": \"" + identifier + "\",\n\t\"iptv_respawn\": false,\n\t\"enabled\": true,\n\t\"scan_result\": 1\n}");
                File.WriteAllText(@folderBrowser.SelectedPath + "\\input\\iptv\\networks\\" + network_uuid + "\\muxes\\" + mux_id + "\\services\\" + svc_id, "{\n\t\"sid\": 1,\n\t\"svcname\": \"" + identifier + "\",\n\t\"dvb_servicetype\": " + (_channels[i].Tag.Contains("Radio") || _channels[i].Tag.Contains("radio") ? 2 : 1) + ",\n\t\"enabled\": true\n}");
                File.WriteAllText(@folderBrowser.SelectedPath + "\\channel\\config\\" + channel_id, "{\n\t\"enabled\": true,\n\t\"name\": \"" + _channels[i].Name + "\",\n\t\"number\": \"" + _channels[i].ID + "\",\n\t\"icon\": \"" + _channels[i].Image + "\",\n\t\"dvr_pre_time\": 0,\n\t\"dvr_pst_time\": 0,\n\t\"services\": [\n\t\t\"" + svc_id + "\"\n\t],\n\t\"tags\": [\n\t\t" + string.Join(",\n\t\t", tagIndexes) + "\n\t],\n\t\"bouquet\": \"\"\n}");

                if (_channels[i].EPG.Length > 0)
                    File.WriteAllText(@folderBrowser.SelectedPath + "\\epggrab\\xmltv\\channels\\" + channel_id, "{\n\t\"name\": \"" + identifier + "\",\n\t\"channels\": [\n\t\t\"" + channel_id + "\"\n\t]\n}");

                exportPlaylist.ReportProgress(i);
            }
            exportPlaylist.ReportProgress(_channels.Count + 1);
        }

        private void exportPlaylist_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            toolStripProgressBar.Value = e.ProgressPercentage;
        }

        private void exportPlaylist_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                toolStripStatusLabel.Text = "Playlist exporting cancelled.";
                MessageBox.Show("Playlist export aborted!", "Export aborted", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                toolStripStatusLabel.Text = "Playlist successfully exported.";
                MessageBox.Show("Successfully exported playlist!", "Playlist exported", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            toolStripStatusLabel.Text = "Select export directory and click Export...";
            toolStripProgressBar.Value = 0;
            tbInterface.Enabled = true;
            tbPath.Enabled = true;
            btnDefault.Enabled = true;
            btnBrowse.Enabled = true;
            btnExport.Enabled = true;
            rbTVHeadEnd34.Enabled = true;
            rbTVHeadEnd39.Enabled = true;
        }
    }
}
